home *** CD-ROM | disk | FTP | other *** search
/ Aminet 1 (Walnut Creek) / Aminet - June 1993 [Walnut Creek].iso / aminet / dev / misc / dialoglib.lha / mx.c < prev    next >
C/C++ Source or Header  |  1993-03-07  |  5KB  |  213 lines

  1. #include <intuition/gadgetclass.h>
  2. #include <libraries/gadtools.h>
  3. #include <graphics/text.h>
  4. #include <proto/diskfont.h>
  5. #include <proto/gadtools.h>
  6. #include <proto/graphics.h>
  7. #include <proto/utility.h>
  8. #include <ctype.h>
  9. #include <string.h>
  10. #include "dialog.h"
  11. #ifdef DEBUG1
  12.     #include <stdio.h>
  13. #endif
  14.  
  15. static LONG countChoices( DialogElement *de )
  16. {
  17.     LONG count = 0;
  18.     STRPTR *label;
  19.  
  20.     if( !de )
  21.         return 0;
  22.  
  23.     if( label = (STRPTR *)GetTagData( GTMX_Labels, 0, de->taglist ) )
  24.         while( *label++ )
  25.             count++;
  26.     return count;
  27. }
  28.  
  29. static VOID setupMX( DialogElement *de )
  30. {
  31.     struct TextAttr *ta;
  32.     struct TextFont *tf;
  33.     struct RastPort rp;
  34.     struct TextExtent te;
  35.     STRPTR *label;
  36.     LONG side1, side2, left, right, height, spacing;
  37.     ULONG place;
  38.     LONG *storage;
  39.  
  40.     if( !de )
  41.         return;
  42.  
  43.     de->idcmp_mask |= MXIDCMP | IDCMP_REFRESHWINDOW | IDCMP_VANILLAKEY;
  44.  
  45.     storage = (LONG *)GetTagData( DA_Storage, 0, de->taglist );
  46.     if( storage )
  47.         *storage = GetTagData( GTMX_Active, 0, de->taglist );
  48.  
  49.     ta = (struct TextAttr *)GetTagData( NGDA_TextAttr, 0, de->taglist );
  50.     if( !ta )
  51.         return;
  52.     tf = OpenDiskFont( ta );
  53.     if( !tf )
  54.         return;
  55.     InitRastPort( &rp );
  56.     SetFont( &rp, tf );
  57.  
  58.     spacing = GetTagData( GTMX_Spacing, 1, de->taglist );
  59.     side1 = height = 0;
  60.     if( label = (STRPTR *)GetTagData( GTMX_Labels, 0, de->taglist ) )
  61.         while( *label )
  62.         {
  63.             LONG width;
  64.  
  65.             TextExtent( &rp, *label, strlen( *label ), &te );
  66.             width = te.te_Extent.MaxX + 1 - te.te_Extent.MinX;
  67.             if( width > side1 )
  68.                 side1 = width;
  69.             height += te.te_Extent.MaxY + 1 - te.te_Extent.MinY + spacing;
  70.             label++;
  71.         }
  72.     side1 += INTERWIDTH;    /* INTERWIDTH is the distance between text and radio button */
  73.     side2 = 17;                /* 17 is the width of the radio button */
  74.  
  75.     CloseFont( tf );
  76.  
  77.     place = getTextPlacement( GetTagData( NGDA_Flags, 0, de->taglist ), PLACETEXT_LEFT );
  78.     switch( place )
  79.     {
  80.     case PLACETEXT_LEFT:
  81.         left = side1;
  82.         right = side2;
  83.         break;
  84.     case PLACETEXT_RIGHT:
  85.         left = side2;
  86.         right = side1;
  87.         break;
  88.     }
  89.     setMinLeftExtent( de, left );
  90.     setMaxLeftExtent( de, left );
  91.     setMinRightExtent( de, right );
  92.     setMaxRightExtent( de, right );
  93.     setMinHeight( de, height );
  94.     setMaxHeight( de, height );
  95. }
  96.  
  97. static ULONG layoutMX( DialogElement *de, LayoutMessage *lm )
  98. {
  99.     struct NewGadget ng;
  100.     ULONG error = DIALOGERR_OK;
  101.  
  102.     if( !de )
  103.         return DIALOGERR_BAD_ARGS;
  104.     if( !lm )
  105.         return DIALOGERR_BAD_ARGS;
  106.  
  107. #ifdef DEBUG1
  108.     printf(
  109.     "layoutMX : x %d, y %d, width %d, height %d, left %d, right %d, top %d, bottom %d\n",
  110.         lm->lm_X, lm->lm_Y, lm->lm_Width, lm->lm_Height,
  111.         lm->lm_Left, lm->lm_Right, lm->lm_Top, lm->lm_Bottom );
  112. #endif
  113.     ng.ng_GadgetText = (UBYTE *)GetTagData( NGDA_GadgetText, 0, de->taglist );
  114.     ng.ng_TextAttr = (struct TextAttr *)GetTagData( NGDA_TextAttr, 0, de->taglist );
  115.     ng.ng_VisualInfo = (APTR)GetTagData( NGDA_VisualInfo, 0, de->taglist );
  116.     ng.ng_Flags = GetTagData( NGDA_Flags, 0, de->taglist );
  117.     ng.ng_LeftEdge = lm->lm_X;
  118.     ng.ng_TopEdge = lm->lm_Y;
  119.     switch( getTextPlacement( ng.ng_Flags, PLACETEXT_LEFT ) )
  120.     {
  121.     case PLACETEXT_RIGHT:
  122.         ng.ng_LeftEdge -= lm->lm_Left;
  123.         break;
  124.     }
  125.     de->object = CreateGadgetA( MX_KIND, *lm->lm_PreviousPtr, &ng, de->taglist );
  126.     *lm->lm_PreviousPtr = de->object;    /* advance "previous" pointer to new object */
  127.     if( !de->object )
  128.         error = DIALOGERR_NO_MEMORY;
  129.     return error;
  130. }
  131.  
  132. static DialogElement *matchMX( DialogElement *de, MatchMessage *mm )
  133. {
  134.     struct IntuiMessage *imsg;
  135.     struct TagItem *tag;
  136.     DialogElement *match = NULL;
  137.     LONG *storage;
  138.  
  139.     if( !de )
  140.         return NULL;
  141.     if( !mm )
  142.         return NULL;
  143.  
  144.     storage = (LONG *)GetTagData( DA_Storage, 0, de->taglist );
  145.  
  146.     imsg = mm->mm_IntuiMsg;
  147.     switch( imsg->Class )
  148.     {
  149.     case IDCMP_GADGETUP:
  150.         if( de->object == imsg->IAddress )
  151.         {
  152.             if( storage )
  153.                 *storage = (ULONG)imsg->Code;
  154.             match = de;
  155.         }
  156.         break;
  157.     case IDCMP_VANILLAKEY:
  158.         if( storage )
  159.             if( tag = FindTagItem( DA_EquivalentKey, de->taglist ) )
  160.                 if( imsg->Code == tolower( tag->ti_Data ) )
  161.                 {
  162.                     if( *storage < countChoices( de ) - 1 )
  163.                         (*storage)++;
  164.                     else
  165.                         *storage = 0;
  166.                     GT_SetGadgetAttrs( de->object, imsg->IDCMPWindow, NULL,
  167.                         GTMX_Active, *storage,
  168.                         TAG_DONE );
  169.                     match = de;
  170.                 }
  171.                 else if( imsg->Code == toupper( tag->ti_Data ) )
  172.                 {
  173.                     if( *storage > 0 )
  174.                         (*storage)--;
  175.                     else
  176.                         *storage = countChoices( de ) - 1;
  177.                     GT_SetGadgetAttrs( de->object, imsg->IDCMPWindow, NULL,
  178.                         GTMX_Active, *storage,
  179.                         TAG_DONE );
  180.                     match = de;
  181.                 }
  182.         break;
  183.     }
  184.     return match;
  185. }
  186.  
  187. ULONG dispatchMX( struct Hook *hook, DialogElement *de, DialogMessage *dm )
  188. {
  189.     ULONG result;
  190.  
  191.     switch( dm->dm_MethodID )
  192.     {
  193.     case DIALOGM_GETSTRUCT:
  194.         result = DESF_VBaseline;
  195.         break;
  196.     case DIALOGM_SETUP:
  197.         setupMX( de );
  198.         break;
  199.     case DIALOGM_LAYOUT:
  200.         result = layoutMX( de, (LayoutMessage *)dm );
  201.         break;
  202.     case DIALOGM_MATCH:
  203.         result = (ULONG)matchMX( de, (MatchMessage *)dm );
  204.         break;
  205.     case DIALOGM_CLEAR:
  206.         break;
  207.     case DIALOGM_SETATTRS:
  208.         setGTAttrs( de, (SetAttrsMessage *)dm );
  209.         break;
  210.     }
  211.     return result;
  212. }
  213.